#include CONFIGURATION_HEADER
#include CALLBACKS_HEADER

#include "native_gecko.h"
#include "em_int.h"
#include "bspconfig.h"
#include "bsp.h"

#include "event_control.h"


void emberAfPluginIdleSleepTickCallback(void)
{
	// Turn interrupts off so that we can safely determine whether we can sleep
	// or idle.  Both halSleepForMilliseconds and emberMarkTaskIdle forcibly
	// enable interrupts.  We can call neither function or exactly one of them
	// without risking a race condition.  Note that if we don't call either, we
	// have to enable interrupts ourselves.
	INT_Disable();

	/* Query the stack to find out how long we are allowed to sleep. It is the
	 * duration to its next event. */
	uint32_t durationMs = gecko_can_sleep_ms();

	if (durationMs)
	{
		durationMs = msToNextEvent(emAppEvents, durationMs);

		// If the sleep duration is below our minimum threshold, we don't bother
		// sleeping.  It takes time to shut everything down and bring everything
		// back up and, at some point, it becomes useless to sleep.  We also give
		// the application one last chance to stay awake if it wants.  If the
		// duration is long enough and the application says okay, we will sleep.
		// Otherwise, we will try to idle instead.
		if (SILABS_AF_PLUGIN_IDLE_SLEEP_MINIMUM_DURATION_MS <= durationMs
				&& emberAfPluginIdleSleepOkToSleepCallback(durationMs))
		{
			/* Try to sleep for specified duration. */
			uint32_t sleptDurationMs = gecko_sleep_for_ms(durationMs);
			/* Call wake up callback with the actual duration we slept. */
			emberAfPluginIdleSleepWakeUpCallback(sleptDurationMs);
		}
	}

	// If we are here, it means we did not sleep or idle.  Interrupts are still
	// disabled at this point, so we have to enable them again.
	INT_Enable();
}

